package org.jcodetools.collection;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 集合操作工具类
 */
public class CollectionUtils {
    /*必秒重复创建对象常量*/
    private static Integer INTEGER_ONE = new Integer(1);

    /**
     * 判断给定集合是否为空
     *
     * @param coll 参数coll
     * @return 返回布尔值。true：为空，false：非空
     */
    public static boolean isEmpty(Collection<?> coll) {
        return null == coll || coll.isEmpty();
    }

    /**
     * 判断给定的map对象参数是否为空
     *
     * @param map 入参
     * @return 返回布尔值。true：表示为空； false：表示非空
     */
    public static boolean isEmpty(Map<?, ?> map) {
        return (map == null || map.isEmpty());
    }

    /**
     * 当且仅当两个集合拥有相同的基数和相同的元素时返回，返回true表示指定的两个集合相同。
     *
     * @param a 第一个集合，不能为空
     * @param b 第二个集合，不能为空
     * @return 返回true表示另个集合具有相同的基数和相同的元素
     */
    public static boolean isEqualCollection(final Collection a, final Collection b) {
        if (a.size() != b.size()) {
            return false;
        } else {
            Map mapa = getCardinalityMap(a);
            Map mapb = getCardinalityMap(b);
            if (mapa.size() != mapb.size()) {
                return false;
            } else {
                Iterator it = mapa.keySet().iterator();
                while (it.hasNext()) {
                    Object obj = it.next();
                    if (getFreq(obj, mapa) != getFreq(obj, mapb)) {
                        return false;
                    }
                }
                return true;
            }
        }
    }

    /**
     * 将指定的集合{@link Collection}进行循环遍历，并将当前元素出现的次数保存到指定整型集合中
     *
     * @param coll 指定的集合参数
     * @return 返回填充的整型集合结果
     */
    public static Map getCardinalityMap(final Collection coll) {
        Map count = new HashMap();
        for (Iterator it = coll.iterator(); it.hasNext(); ) {
            Object obj = it.next();
            Integer c = (Integer) (count.get(obj));
            if (c == null) {
                count.put(obj, INTEGER_ONE);
            } else {
                count.put(obj, new Integer(c.intValue() + 1));
            }
        }
        return count;
    }

    /**
     * 获得指定的对象obj在指定的freqMap对象中的键值，不存在则返回0；
     *
     * @param obj     指定的结合
     * @param freqMap Map对象
     * @return 返回obj对象在freqMap中键值
     */
    private static final int getFreq(final Object obj, final Map freqMap) {
        Integer count = (Integer) freqMap.get(obj);
        if (count != null) {
            return count.intValue();
        }
        return 0;
    }
}
